Here, we explore bottom temperature and fishing as potential drivers of spatial beta diversity across trawl regions.

library(data.table)
library(ggplot2)
library(lme4)
library(lmerTest)
library(MuMIn)

###Pull in datatable with dissimilarities, reg characteristics, fishing, and temperature


#from local (will have to change)
dissimilarities_temp_fishing_regstats <- readRDS(here::here("output","distance_decay","dissimilarities_temp_fishing_regstats.rds"))

###Palette for Plotting Palette for plotting all 37 survey units (Prep for eventual plots)

survey_unit.list <- levels(dissimilarities_temp_fishing_regstats[,factor(survey_unit)])

palette_37 <- c(
  "#5A5156", #AI
  "#F6222E", #CHL
  "#F8A19F", #DFO-NF
  "#16FF32", #DFO-QCS
  "#DF00DB", #BITS-1
  "#DB8EDA", #BITS-4
  "#325A9B", #EBS
  "#3283FE", #EVHOE
  "#FEAF16", #FR-CGFS
  "#1C8356", #GMEX-Summer
  "#C4451C", #GOA
  "#85660D", #GRL-DE
  "#B0009F", #GSL-N
  "#BF79B8", #GSL-S
  "#1CBE4F", #ICE-GFS
  "#782AB6", #IE-IGFS
  "#90AD1C", #MEDITS
  "#6B003A", #NAM
  "#A75B00", #NEUS-Fall
  "#E3B072", #NEUS-Spring
  "#02E8B6", #NIGFS-1
  "#97E7D5", #NIGFS-4
  "#B00068", #Nor-BTS-3
  "#00B9E3", #NS-IBTS-1
  "#95E2F4", #NS-IBTS-3
  "#B3CE73", #NZ-CHAT
  "#689500", #NZ-ECSI
  "#AAF400", #NZ-WCSI
  "#AA0DFE", #PT-IBTS
  "#FA0087", #S-GEORG
  "#DEA0FD", #SCS-Summer
  "#FCEF88", #SEUS-fall
  "#A59405", #SEUS-spring
  "#FCE100", #SEUS-summer
  "#C075A6", #WCANN
  "#BDCDFF", #ZAF-ATL
  "#003EFF"  #ZAF-IND
)

color_link <- data.table(survey_unit = survey_unit.list,hex = palette_37)

Add names for plotting


name_helper <- data.table(Survey_Name_Season = c("Aleutian Islands",
                                    "Baltic Sea Q1",
                                    "Baltic Sea Q4",
                                    "Chile",
                                    "Newfoundland",
                                    "Queen Charlotte Sound",
                                    "Eastern Bering Sea",
                                    "Bay of Biscay",
                                    "English Channel",
                                    "Gulf of Mexico",
                                    "Gulf of Alaska",
                                    "Greenland",
                                    "N Gulf of St. Lawrence",
                                    "S Gulf of St. Lawrence",
                                    "Iceland",
                                    "Irish Sea",
                                    "Mediterranean",
                                    "Namibia",
                                    "NE US Fall",
                                    "NE US Spring",
                                    "N Ireland Q1",
                                    "N Ireland Q4",
                                    "Norway",
                                    "N Sea Q1",
                                    "N Sea Q3",
                                    "Chatham Rise",
                                    "E Coast S Island NZ",
                                    "W Coast S Island NZ",
                                    "Portugal",
                                    "S Georgia Straight",
                                  "Scotian Shelf",
                                  "SE US Fall",
                                  "SE US Spring",
                                  "SE US Summer",
                                  "W Coast US",
                                  "Atlantic Ocean ZA",
                                  "Indian Ocean ZA"),
                          survey_unit = c(
                                  "AI",        
                                  "BITS-1",    
                                  "BITS-4",    
                                  "CHL",       
                                  "DFO-NF",    
                                  "DFO-QCS",   
                                  "EBS",       
                                  "EVHOE",     
                                  "FR-CGFS",   
                                  "GMEX-Summer",
                                  "GOA",       
                                  "GRL-DE",    
                                  "GSL-N",     
                                  "GSL-S",     
                                  "ICE-GFS",   
                                  "IE-IGFS",   
                                  "MEDITS",    
                                  "NAM",       
                                  "NEUS-Fall", 
                                  "NEUS-Spring",
                                  "NIGFS-1",   
                                  "NIGFS-4",   
                                  "Nor-BTS-3", 
                                  "NS-IBTS-1", 
                                  "NS-IBTS-3", 
                                  "NZ-CHAT",   
                                  "NZ-ECSI",   
                                  "NZ-WCSI",   
                                  "PT-IBTS",   
                                  "S-GEORG",   
                                  "SCS-SUMMER",
                                  "SEUS-fall", 
                                  "SEUS-spring",
                                  "SEUS-summer",
                                  "WCANN",     
                                  "ZAF-ATL",   
                                  "ZAF-IND"   
                          ))

color_link <- color_link[name_helper, on = "survey_unit"]

###First, we built mixed models with raw temperature predictors as fixed effects and survey as random slope and intercept - Mean bottom temp 12 months before survey - Max bottom temp 12 years before survey - Min bottom temp 12 years before survey - Bottom temp seasonality 12 months before survey - Heterogeneity (SD) of mean bottom temp 12 months before survey - Heterogeneity (SD) of max bottom temp 12 months before survey - Heterogeneity (SD) of min bottom temp 12 months before survey - Heterogeneity (SD) of bottom temp seasonalty 12 months before survey

#from local (will have to change)
balanced_dissimilarity_sbt_model_results <- readRDS(here::here("output","balanced_dissimilarity_sbt_model_results.rds"))

setorder(balanced_dissimilarity_sbt_model_results,-AICc)

balanced_dissimilarity_sbt_model_results[Scaled == F,]

The standard deviation of mean temperature and the overall mean temperature perform equally well. However, neither explain very much variation at all (R^ of 0.7 and 0.2)

The SD of mean tempereature performs best, but explains little variation. *Note that this plot is just to help visualize data and patterns, it does not plot predicted values from the LME but rather just simple linear models of dissimilarity ~ temp.

ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "SD of mean bottom temperature",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
  scale_color_manual(values = c(palette_37)) +
  geom_smooth(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  theme_classic()


#facet helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "SD of mean bottom temperature",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
  scale_color_manual(values = c(palette_37)) +
  geom_smooth(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  facet_wrap(~survey_unit, scales = "free") +
  theme_classic() + theme(legend.position = "null")

The mean temperature performs equally well, but explains little variation. *Note that this plot is just to help visualize data and patterns, it does not plot predicted values from the LME but rather just simple linear models of dissimilarity ~ temp.

ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "Mean bottom temperature (ËšC)",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
  scale_color_manual(values = c(palette_37)) +
  geom_smooth(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  theme_classic()


#faceted helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "Mean bottom temperature (ËšC)",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  scale_color_manual(values = c(palette_37)) +
  facet_wrap(~survey_unit, scales = "free") +
  geom_smooth(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  theme_classic() +
  theme(legend.position = "null")

###Then, we looked at relative temperature predictors (scaled within a survey region, so, is this year warm or cool for this region) - Relative mean bottom temp 12 months before survey - Relative max bottom temp 12 years before survey - Relative min bottom temp 12 years before survey - Relative bottom temp seasonality 12 months before survey - Relative heterogeneity (SD) of mean bottom temp 12 months before survey - Relative heterogeneity (SD) of max bottom temp 12 months before survey - Relative heterogeneity (SD) of min bottom temp 12 months before survey - Relative heterogeneity (SD) of bottom temp seasonalty 12 months before survey


balanced_dissimilarity_sbt_model_results[Scaled == T,]

The relative mean tempereature performs best, but explains 0 variation. *Note that this plot is just to help visualize data and patterns, it does not plot predicted values from the LME but rather just simple linear models of dissimilarity ~ temp.

ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "Mean bottom temperature scaled",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
  scale_color_manual(values = c(palette_37)) +
  geom_smooth(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  theme_classic()


#faceted helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "Mean bottom temperature scaled",  y = "Bray Curtis balanced dissimilarity") +
  geom_point(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
  scale_color_manual(values = c(palette_37)) +
  geom_smooth(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color  = "black") +
  facet_wrap(~survey_unit, scales = "free") +
  theme_classic() + theme(legend.position = "null")

###Fishing Pressure Alone

#model ranking for fishing only models

#from local (will have to change)
balanced_dissimilarity_fishing_model_results <-readRDS(here::here("output","balanced_dissimilarity_fishing_model_results.Rds"))

setorder(balanced_dissimilarity_fishing_model_results, -AICc)

balanced_dissimilarity_fishing_model_results

Best model only includes survey unit (probably because of differences in baseline dissimilarity across regions)

###Now we’ll look at both fishing and bottom temperature as potential predictors

#model rankings (temp and fishing)
#from local (will have to change)
balanced_dissimilarity_sbt_fishing_model_results <- readRDS(here::here("output", "balanced_dissimilarity_sbt_fishing_model_results.Rds"))

setorder(balanced_dissimilarity_sbt_fishing_model_results, -AICc)
balanced_dissimilarity_sbt_fishing_model_results

Any model with survey as a fixed effect performs better than models without survey as a fixed effect. Also, there is an interaction between fishing and survey in 4 of the top 5 performing models.

Significant positive interaction (higher dissimilarity at higher fishing) - Newfoundland

Significant negative interaction (higher dissimilarity at lower fishing) - Eastern Bering Sea - France - Gulf of Alaska - Gulf of St. Lawrence S - Northeast US Fall - Ireland 4th quarter - North Sea (1st and 3rd quarter) - West Coast and East Coast of South Island of New Zealand - South Georgia - Scotian Shelf Summer Survey

Plot just dissimilarity ~ relative fishing pressure coefficients of each region (Like figure 1b) *Note, may be better to include survey as a fixed effect, but below we include as random slope and intercept instead.

#lmer with fishing as fixed and survey as random slope and intercept
#fishing and random slope and intercept for survey
allreg_dissimilarity_fishing_mean_mod <- lmer(bray_curtis_dissimilarity_balanced_mean ~ summed_tonnes_scaled_byreg + (1 + summed_tonnes_scaled_byreg|survey_unit), data = dissimilarities_temp_fishing_regstats)
                 

 # see group coefficients and confidence intervals
fishing_model_coefs_reduced <- data.table(transform(as.data.frame(ranef(allreg_dissimilarity_fishing_mean_mod)), lwr = condval - 1.96*condsd, upr = condval + 1.96*condsd))
#https://stackoverflow.com/questions/69805532/extract-the-confidence-intervals-of-lmer-random-effects-plotted-with-dotplotra


#ONLY SLOPES
fishing_model_coefs_reduced <- fishing_model_coefs_reduced[term == "summed_tonnes_scaled_byreg",]

fishing_model_coefs_reduced[,survey_unit := grp][,summed_tonnes_scaled_byreg := condval]


fishing_model_coefs_reduced[,Slope_Direction := ifelse(summed_tonnes_scaled_byreg > 0, "Positive","Negative")]

#
fishing_model_coefs_reduced <- fishing_model_coefs_reduced[color_link, on = "survey_unit"]


#does it cross zero?
fishing_model_coefs_reduced[,significant := ifelse(lwr >0 & upr>0,T,ifelse(lwr<0 & upr<0,T,F))]

#delete all obs that are significant
fishing_model_coefs_reduced.r <- fishing_model_coefs_reduced[significant == F,]

#order table by coefficient
setorder(fishing_model_coefs_reduced, summed_tonnes_scaled_byreg)

BC_balanced_fishing_model_coefs_reduced.unique <- unique(fishing_model_coefs_reduced[,.(condval,condsd, lwr, upr, survey_unit, summed_tonnes_scaled_byreg, Slope_Direction, hex, Survey_Name_Season, significant)]) 

#extract color hexes
#year adj coef order
color_year_adj_order <-BC_balanced_fishing_model_coefs_reduced.unique[,hex]

#alphabetical order
BC_balanced_fishing_model_coefs_reduced.unique.alpha <- setorder(BC_balanced_fishing_model_coefs_reduced.unique, Survey_Name_Season)
color_alpha_order <- BC_balanced_fishing_model_coefs_reduced.unique.alpha[,hex]

ggplot() +
    geom_errorbar(data = fishing_model_coefs_reduced, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg, label = Survey_Name_Season, ymin = lwr, ymax = upr), fill = "grey", width = 0) + #add confidence intervals
  geom_point(data = fishing_model_coefs_reduced, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg, label = Survey_Name_Season, 
      fill = Slope_Direction), stat = 'identity', shape = 21, color = "black") +
  scale_fill_manual(values = c("white","black"), name = "Slope Direction") +
  geom_point(data = fishing_model_coefs_reduced.r, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg, 
          label = Survey_Name_Season), stat = 'identity', fill = "grey",color = "grey", shape = 21) +
  geom_hline(yintercept = 0) +
  xlab("Survey unit") +
  ylab("Balanced BC dissimilarity ~\nrelative fishing pressure") +
  coord_flip() +
  theme_classic()
Warning: Ignoring unknown parameters: `fill`Warning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: label

#scatterplot
dissimilarities_temp_fishing_regstats.na <- na.omit(dissimilarities_temp_fishing_regstats, cols = "summed_tonnes_scaled_byreg") #delete any rows with NAs

#Predicted values
dissimilarities_temp_fishing_regstats.na$pred_summed_tonnes_scaled_byreg <- predict(allreg_dissimilarity_fishing_mean_mod,re.form=NA)  ## population level
dissimilarities_temp_fishing_regstats.na$pred_summed_tonnes_scaled_byreg_individual <- predict(allreg_dissimilarity_fishing_mean_mod) ## individual level

#confidence intervals
fishing_confit <- confint(allreg_dissimilarity_fishing_mean_mod, oldNames = F)
Computing profile confidence intervals ...
#upper lower bounds from confidence intervals
dissimilarities_temp_fishing_regstats.na[,pred_summed_tonnes_scaled_byreg_lwr := fishing_confit[5,1] + fishing_confit[6,1]*summed_tonnes_scaled_byreg]#lower confidence interval
dissimilarities_temp_fishing_regstats.na[,pred_summed_tonnes_scaled_byreg_upr := fishing_confit[5,2] + fishing_confit[6,2]*summed_tonnes_scaled_byreg]#upper confidence interval


#for all regions
ggplot(data = dissimilarities_temp_fishing_regstats.na) +
  labs(x = "Relative fishing pressure",  y = "BC balanced dissimilarity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg_individual, color = survey_unit)) +
  geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg), lwd = 1) +
  scale_color_manual(values =  palette_37) +
  theme_classic()




#for all regions faceted
ggplot(data = dissimilarities_temp_fishing_regstats.na) +
  labs(x = "Relative fishing pressure",  y = "BC balanced dissimilarity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg_individual, color = survey_unit)) +
  scale_color_manual(values =  palette_37) +
  facet_wrap(~survey_unit, scales = "free") +
  theme_classic() +
    theme(legend.position = "null")

NA
NA
NA

Other variables to consider

Species number in a year vs. dissimilarity

ggplot(data = dissimilarities_temp_fishing_regstats) +
  labs(x = "Spp number",  y = "BC balanced dissimilarity") +
  geom_point(aes(x = spp_count_annual, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
  scale_color_manual(values =  palette_37) +
 # facet_wrap(~survey_unit, scales = "free") +
  theme_classic() +
    theme(legend.position = "null")

Species number in a year vs. dissimilarity ~ year coefficient

dissimilarities_temp_fishing_regstats.unique <- unique(dissimilarities_temp_fishing_regstats[,.(year, spp_count_annual, bray_coef, survey_unit)])

ggplot(data = dissimilarities_temp_fishing_regstats.unique) +
  labs(x = "Spp number",  y = "Bray Curtis dissimilarity ~ year coefficient") +
  geom_point(aes(x = spp_count_annual, y = bray_coef, color = survey_unit), alpha = 0.3) +
  scale_color_manual(values =  palette_37) +
  geom_hline(yintercept = 0) +
  theme_classic()

Regions that are differentiating (positive slope) tend to have fewer #s of species. The few regions with a lot of species (over 150; Gulf of Mexico, West Coast US, Northeast US, Gulf of Alaska), all have negative coefficients (homogenizing). This is the opposite of what I would have expected, as more species across a survey region would intuitively allow for more opportunities to differentiate.

LS0tCnRpdGxlOiAiRHJpdmVycyBvZiBEaXNzaW1pbGFyaXR5IFdhbGsgVGhyb3VnaCAoQm90dG9tIHRlbXAsIGJhbGFuY2VkIEJyYXkgQ3VydGlzIERpc3NpbWlsYXJpdHkpIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpIZXJlLCB3ZSBleHBsb3JlIGJvdHRvbSB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyBhcyBwb3RlbnRpYWwgZHJpdmVycyBvZiBzcGF0aWFsIGJldGEgZGl2ZXJzaXR5IGFjcm9zcyB0cmF3bCByZWdpb25zLgoKYGBge3Igc2V0dXB9CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkoTXVNSW4pCmBgYAoKIyMjUHVsbCBpbiBkYXRhdGFibGUgd2l0aCBkaXNzaW1pbGFyaXRpZXMsIHJlZyBjaGFyYWN0ZXJpc3RpY3MsIGZpc2hpbmcsIGFuZCB0ZW1wZXJhdHVyZQpgYGB7cn0KCiNmcm9tIGxvY2FsICh3aWxsIGhhdmUgdG8gY2hhbmdlKQpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzIDwtIHJlYWRSRFMoaGVyZTo6aGVyZSgib3V0cHV0IiwiZGlzdGFuY2VfZGVjYXkiLCJkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLnJkcyIpKQoKYGBgCgojIyNQYWxldHRlIGZvciBQbG90dGluZwpQYWxldHRlIGZvciBwbG90dGluZyBhbGwgMzcgc3VydmV5IHVuaXRzCihQcmVwIGZvciBldmVudHVhbCBwbG90cykKYGBge3IgbGluayBjb2xvcnMgdG8gc3VydmV5IHVuaXRzfQpzdXJ2ZXlfdW5pdC5saXN0IDwtIGxldmVscyhkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzWyxmYWN0b3Ioc3VydmV5X3VuaXQpXSkKCnBhbGV0dGVfMzcgPC0gYygKICAiIzVBNTE1NiIsICNBSQogICIjRjYyMjJFIiwgI0NITAogICIjRjhBMTlGIiwgI0RGTy1ORgogICIjMTZGRjMyIiwgI0RGTy1RQ1MKICAiI0RGMDBEQiIsICNCSVRTLTEKICAiI0RCOEVEQSIsICNCSVRTLTQKICAiIzMyNUE5QiIsICNFQlMKICAiIzMyODNGRSIsICNFVkhPRQogICIjRkVBRjE2IiwgI0ZSLUNHRlMKICAiIzFDODM1NiIsICNHTUVYLVN1bW1lcgogICIjQzQ0NTFDIiwgI0dPQQogICIjODU2NjBEIiwgI0dSTC1ERQogICIjQjAwMDlGIiwgI0dTTC1OCiAgIiNCRjc5QjgiLCAjR1NMLVMKICAiIzFDQkU0RiIsICNJQ0UtR0ZTCiAgIiM3ODJBQjYiLCAjSUUtSUdGUwogICIjOTBBRDFDIiwgI01FRElUUwogICIjNkIwMDNBIiwgI05BTQogICIjQTc1QjAwIiwgI05FVVMtRmFsbAogICIjRTNCMDcyIiwgI05FVVMtU3ByaW5nCiAgIiMwMkU4QjYiLCAjTklHRlMtMQogICIjOTdFN0Q1IiwgI05JR0ZTLTQKICAiI0IwMDA2OCIsICNOb3ItQlRTLTMKICAiIzAwQjlFMyIsICNOUy1JQlRTLTEKICAiIzk1RTJGNCIsICNOUy1JQlRTLTMKICAiI0IzQ0U3MyIsICNOWi1DSEFUCiAgIiM2ODk1MDAiLCAjTlotRUNTSQogICIjQUFGNDAwIiwgI05aLVdDU0kKICAiI0FBMERGRSIsICNQVC1JQlRTCiAgIiNGQTAwODciLCAjUy1HRU9SRwogICIjREVBMEZEIiwgI1NDUy1TdW1tZXIKICAiI0ZDRUY4OCIsICNTRVVTLWZhbGwKICAiI0E1OTQwNSIsICNTRVVTLXNwcmluZwogICIjRkNFMTAwIiwgI1NFVVMtc3VtbWVyCiAgIiNDMDc1QTYiLCAjV0NBTk4KICAiI0JEQ0RGRiIsICNaQUYtQVRMCiAgIiMwMDNFRkYiICAjWkFGLUlORAopCgpjb2xvcl9saW5rIDwtIGRhdGEudGFibGUoc3VydmV5X3VuaXQgPSBzdXJ2ZXlfdW5pdC5saXN0LGhleCA9IHBhbGV0dGVfMzcpCmBgYAoKQWRkIG5hbWVzIGZvciBwbG90dGluZwpgYGB7ciBhZGQgbmFtZXMgZm9yIHBsb3R0aW5nfQoKbmFtZV9oZWxwZXIgPC0gZGF0YS50YWJsZShTdXJ2ZXlfTmFtZV9TZWFzb24gPSBjKCJBbGV1dGlhbiBJc2xhbmRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbHRpYyBTZWEgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFsdGljIFNlYSBRNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGlsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZXdmb3VuZGxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUXVlZW4gQ2hhcmxvdHRlIFNvdW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVhc3Rlcm4gQmVyaW5nIFNlYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYXkgb2YgQmlzY2F5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZ2xpc2ggQ2hhbm5lbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHdWxmIG9mIE1leGljbyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHdWxmIG9mIEFsYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHcmVlbmxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBHdWxmIG9mIFN0LiBMYXdyZW5jZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTIEd1bGYgb2YgU3QuIExhd3JlbmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkljZWxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSXJpc2ggU2VhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lZGl0ZXJyYW5lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmFtaWJpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORSBVUyBGYWxsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FIFVTIFNwcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIElyZWxhbmQgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBJcmVsYW5kIFE0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vcndheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIFNlYSBRMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIFNlYSBRMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGF0aGFtIFJpc2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRSBDb2FzdCBTIElzbGFuZCBOWiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXIENvYXN0IFMgSXNsYW5kIE5aIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlMgR2VvcmdpYSBTdHJhaWdodCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NvdGlhbiBTaGVsZiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0UgVVMgRmFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0UgVVMgU3ByaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRSBVUyBTdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlcgQ29hc3QgVVMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0bGFudGljIE9jZWFuIFpBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmRpYW4gT2NlYW4gWkEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUkiLCAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy0xIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy00IiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0hMIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLU5GIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLVFDUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUJTIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVZIT0UiLCAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRlItQ0dGUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR01FWC1TdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdPQSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdSTC1ERSIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1TIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklDRS1HRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklFLUlHRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1FRElUUyIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5BTSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtRmFsbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtU3ByaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy0xIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy00IiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3ItQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1DSEFUIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1FQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1XQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQVC1JQlRTIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTLUdFT1JHIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQ1MtU1VNTUVSIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLWZhbGwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLXNwcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0VVUy1zdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldDQU5OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1BVEwiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1JTkQiICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKCmNvbG9yX2xpbmsgPC0gY29sb3JfbGlua1tuYW1lX2hlbHBlciwgb24gPSAic3VydmV5X3VuaXQiXQoKYGBgCgoKIyMjRmlyc3QsIHdlIGJ1aWx0IG1peGVkIG1vZGVscyB3aXRoIHJhdyB0ZW1wZXJhdHVyZSBwcmVkaWN0b3JzIGFzIGZpeGVkIGVmZmVjdHMgYW5kIHN1cnZleSBhcyByYW5kb20gc2xvcGUgYW5kIGludGVyY2VwdAotIE1lYW4gYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBNYXggYm90dG9tIHRlbXAgMTIgeWVhcnMgYmVmb3JlIHN1cnZleQotIE1pbiBib3R0b20gdGVtcCAxMiB5ZWFycyBiZWZvcmUgc3VydmV5Ci0gQm90dG9tIHRlbXAgc2Vhc29uYWxpdHkgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBIZXRlcm9nZW5laXR5IChTRCkgb2YgbWVhbiBib3R0b20gdGVtcCAxMiBtb250aHMgYmVmb3JlIHN1cnZleQotIEhldGVyb2dlbmVpdHkgKFNEKSBvZiBtYXggYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBIZXRlcm9nZW5laXR5IChTRCkgb2YgbWluIGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gSGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIGJvdHRvbSB0ZW1wIHNlYXNvbmFsdHkgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKCgpgYGB7ciByYXcgdGVtcCBtb2RlbCByZXN1bHRzfQojZnJvbSBsb2NhbCAod2lsbCBoYXZlIHRvIGNoYW5nZSkKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0cyA8LSByZWFkUkRTKGhlcmU6OmhlcmUoIm91dHB1dCIsImJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfc2J0X21vZGVsX3Jlc3VsdHMucmRzIikpCgpzZXRvcmRlcihiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9tb2RlbF9yZXN1bHRzLC1BSUNjKQoKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0c1tTY2FsZWQgPT0gRixdCmBgYApUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIG1lYW4gdGVtcGVyYXR1cmUgYW5kIHRoZSBvdmVyYWxsIG1lYW4gdGVtcGVyYXR1cmUgcGVyZm9ybSBlcXVhbGx5IHdlbGwuIEhvd2V2ZXIsIG5laXRoZXIgZXhwbGFpbiB2ZXJ5IG11Y2ggdmFyaWF0aW9uIGF0IGFsbCAoUl4gb2YgMC43IGFuZCAwLjIpCgpUaGUgU0Qgb2YgbWVhbiB0ZW1wZXJlYXR1cmUgcGVyZm9ybXMgYmVzdCwgYnV0IGV4cGxhaW5zIGxpdHRsZSB2YXJpYXRpb24uIAoqTm90ZSB0aGF0IHRoaXMgcGxvdCBpcyBqdXN0IHRvIGhlbHAgdmlzdWFsaXplIGRhdGEgYW5kIHBhdHRlcm5zLCAgaXQgZG9lcyBub3QgcGxvdCBwcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIExNRSBidXQgcmF0aGVyIGp1c3Qgc2ltcGxlIGxpbmVhciBtb2RlbHMgb2YgZGlzc2ltaWxhcml0eSB+IHRlbXAuCmBgYHtyIHBsb3QgZGlzc2ltaWxhcml0eSB2cy4gU0Qgb2YgbWVhbiB0ZW1wZXJhdHVyZX0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNEIG9mIG1lYW4gYm90dG9tIHRlbXBlcmF0dXJlIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIHN0YXQ9InNtb290aCIsIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhwYWxldHRlXzM3KSkgKwogIGdlb21fc21vb3RoKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKQoKI2ZhY2V0IGhlbHBmdWwgZm9yIHZpc3VhbGl6YXRpb24KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNEIG9mIG1lYW4gYm90dG9tIHRlbXBlcmF0dXJlIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIHN0YXQ9InNtb290aCIsIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhwYWxldHRlXzM3KSkgKwogIGdlb21fc21vb3RoKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIGZhY2V0X3dyYXAofnN1cnZleV91bml0LCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIpCgpgYGAKClRoZSBtZWFuIHRlbXBlcmF0dXJlIHBlcmZvcm1zIGVxdWFsbHkgd2VsbCwgYnV0IGV4cGxhaW5zIGxpdHRsZSB2YXJpYXRpb24uIAoqTm90ZSB0aGF0IHRoaXMgcGxvdCBpcyBqdXN0IHRvIGhlbHAgdmlzdWFsaXplIGRhdGEgYW5kIHBhdHRlcm5zLCAgaXQgZG9lcyBub3QgcGxvdCBwcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIExNRSBidXQgcmF0aGVyIGp1c3Qgc2ltcGxlIGxpbmVhciBtb2RlbHMgb2YgZGlzc2ltaWxhcml0eSB+IHRlbXAuCmBgYHtyIHBsb3QgZGlzc2ltaWxhcml0eSB2cy4gbWVhbiB0ZW1wZXJhdHVyZX0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIk1lYW4gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9hdmcsIHkgPSBicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X2JhbGFuY2VkX21lYW4sIGNvbG9yID0gc3VydmV5X3VuaXQpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fbGluZShhZXMoeCA9IHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKQoKI2ZhY2V0ZWQgaGVscGZ1bCBmb3IgdmlzdWFsaXphdGlvbgpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMpICsKICBsYWJzKHggPSAiTWVhbiBib3R0b20gdGVtcGVyYXR1cmUgKMuaQykiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMocGFsZXR0ZV8zNykpICsKICBmYWNldF93cmFwKH5zdXJ2ZXlfdW5pdCwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm51bGwiKQpgYGAKCgojIyNUaGVuLCB3ZSBsb29rZWQgYXQgcmVsYXRpdmUgdGVtcGVyYXR1cmUgcHJlZGljdG9ycyAoc2NhbGVkIHdpdGhpbiBhIHN1cnZleSByZWdpb24sIHNvLCBpcyB0aGlzIHllYXIgd2FybSBvciBjb29sIGZvciB0aGlzIHJlZ2lvbikKLSBSZWxhdGl2ZSBtZWFuIGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgbWF4IGJvdHRvbSB0ZW1wIDEyIHllYXJzIGJlZm9yZSBzdXJ2ZXkKLSBSZWxhdGl2ZSBtaW4gYm90dG9tIHRlbXAgMTIgeWVhcnMgYmVmb3JlIHN1cnZleQotIFJlbGF0aXZlIGJvdHRvbSB0ZW1wIHNlYXNvbmFsaXR5IDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgaGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIG1lYW4gYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBSZWxhdGl2ZSBoZXRlcm9nZW5laXR5IChTRCkgb2YgbWF4IGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgaGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIG1pbiBib3R0b20gdGVtcCAxMiBtb250aHMgYmVmb3JlIHN1cnZleQotIFJlbGF0aXZlIGhldGVyb2dlbmVpdHkgKFNEKSBvZiBib3R0b20gdGVtcCBzZWFzb25hbHR5IDEyIG1vbnRocyBiZWZvcmUgc3VydmV5CgpgYGB7ciBzY2FsZWQgdGVtcCBtb2RlbCByZXN1bHRzfQoKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0c1tTY2FsZWQgPT0gVCxdCmBgYApUaGUgcmVsYXRpdmUgbWVhbiB0ZW1wZXJlYXR1cmUgcGVyZm9ybXMgYmVzdCwgYnV0IGV4cGxhaW5zIDAgdmFyaWF0aW9uLiAKKk5vdGUgdGhhdCB0aGlzIHBsb3QgaXMganVzdCB0byBoZWxwIHZpc3VhbGl6ZSBkYXRhIGFuZCBwYXR0ZXJucywgIGl0IGRvZXMgbm90IHBsb3QgcHJlZGljdGVkIHZhbHVlcyBmcm9tIHRoZSBMTUUgYnV0IHJhdGhlciBqdXN0IHNpbXBsZSBsaW5lYXIgbW9kZWxzIG9mIGRpc3NpbWlsYXJpdHkgfiB0ZW1wLgpgYGB7ciBwbG90IGRpc3NpbWlsYXJpdHkgdnMuIHJlbGF0aXZlIG1lYW4gdGVtcGVyYXR1cmV9CmdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cykgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSBzY2FsZWQiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGLCBjb2xvciAgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpCgojZmFjZXRlZCBoZWxwZnVsIGZvciB2aXN1YWxpemF0aW9uCmdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cykgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSBzY2FsZWQiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGLCBjb2xvciAgPSAiYmxhY2siKSArCiAgZmFjZXRfd3JhcCh+c3VydmV5X3VuaXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIikKYGBgCgojIyNGaXNoaW5nIFByZXNzdXJlIEFsb25lCmBgYHtyfQojbW9kZWwgcmFua2luZyBmb3IgZmlzaGluZyBvbmx5IG1vZGVscwoKI2Zyb20gbG9jYWwgKHdpbGwgaGF2ZSB0byBjaGFuZ2UpCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzIDwtcmVhZFJEUyhoZXJlOjpoZXJlKCJvdXRwdXQiLCJiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X2Zpc2hpbmdfbW9kZWxfcmVzdWx0cy5SZHMiKSkKCnNldG9yZGVyKGJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzLCAtQUlDYykKCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzCmBgYApCZXN0IG1vZGVsIG9ubHkgaW5jbHVkZXMgc3VydmV5IHVuaXQgKHByb2JhYmx5IGJlY2F1c2Ugb2YgZGlmZmVyZW5jZXMgaW4gYmFzZWxpbmUgZGlzc2ltaWxhcml0eSBhY3Jvc3MgcmVnaW9ucykKCgojIyNOb3cgd2UnbGwgbG9vayBhdCBib3RoIGZpc2hpbmcgYW5kIGJvdHRvbSB0ZW1wZXJhdHVyZSBhcyBwb3RlbnRpYWwgcHJlZGljdG9ycwoKYGBge3J9CiNtb2RlbCByYW5raW5ncyAodGVtcCBhbmQgZmlzaGluZykKI2Zyb20gbG9jYWwgKHdpbGwgaGF2ZSB0byBjaGFuZ2UpCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfc2J0X2Zpc2hpbmdfbW9kZWxfcmVzdWx0cyA8LSByZWFkUkRTKGhlcmU6OmhlcmUoIm91dHB1dCIsICJiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMuUmRzIikpCgpzZXRvcmRlcihiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMsIC1BSUNjKQpiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMKYGBgCkFueSBtb2RlbCB3aXRoIHN1cnZleSBhcyBhIGZpeGVkIGVmZmVjdCBwZXJmb3JtcyBiZXR0ZXIgdGhhbiBtb2RlbHMgd2l0aG91dCBzdXJ2ZXkgYXMgYSBmaXhlZCBlZmZlY3QuIEFsc28sIHRoZXJlIGlzIGFuIGludGVyYWN0aW9uIGJldHdlZW4gZmlzaGluZyBhbmQgc3VydmV5IGluIDQgb2YgdGhlIHRvcCA1IHBlcmZvcm1pbmcgbW9kZWxzLiAKClNpZ25pZmljYW50IHBvc2l0aXZlIGludGVyYWN0aW9uIChoaWdoZXIgZGlzc2ltaWxhcml0eSBhdCBoaWdoZXIgZmlzaGluZykKLSBOZXdmb3VuZGxhbmQKClNpZ25pZmljYW50IG5lZ2F0aXZlIGludGVyYWN0aW9uIChoaWdoZXIgZGlzc2ltaWxhcml0eSBhdCBsb3dlciBmaXNoaW5nKQotIEVhc3Rlcm4gQmVyaW5nIFNlYQotIEZyYW5jZQotIEd1bGYgb2YgQWxhc2thCi0gR3VsZiBvZiBTdC4gTGF3cmVuY2UgUwotIE5vcnRoZWFzdCBVUyBGYWxsCi0gSXJlbGFuZCA0dGggcXVhcnRlcgotIE5vcnRoIFNlYSAoMXN0IGFuZCAzcmQgcXVhcnRlcikKLSBXZXN0IENvYXN0IGFuZCBFYXN0IENvYXN0IG9mIFNvdXRoIElzbGFuZCBvZiBOZXcgWmVhbGFuZAotIFNvdXRoIEdlb3JnaWEKLSBTY290aWFuIFNoZWxmIFN1bW1lciBTdXJ2ZXkKCgpQbG90IGp1c3QgZGlzc2ltaWxhcml0eSB+IHJlbGF0aXZlIGZpc2hpbmcgcHJlc3N1cmUgY29lZmZpY2llbnRzIG9mIGVhY2ggcmVnaW9uIChMaWtlIGZpZ3VyZSAxYikKKk5vdGUsIG1heSBiZSBiZXR0ZXIgdG8gaW5jbHVkZSBzdXJ2ZXkgYXMgYSBmaXhlZCBlZmZlY3QsIGJ1dCBiZWxvdyB3ZSBpbmNsdWRlIGFzIHJhbmRvbSBzbG9wZSBhbmQgaW50ZXJjZXB0IGluc3RlYWQuIApgYGB7cn0KI2xtZXIgd2l0aCBmaXNoaW5nIGFzIGZpeGVkIGFuZCBzdXJ2ZXkgYXMgcmFuZG9tIHNsb3BlIGFuZCBpbnRlcmNlcHQKI2Zpc2hpbmcgYW5kIHJhbmRvbSBzbG9wZSBhbmQgaW50ZXJjZXB0IGZvciBzdXJ2ZXkKYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCA8LSBsbWVyKGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiB+IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgKDEgKyBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZ3xzdXJ2ZXlfdW5pdCksIGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKQogICAgICAgICAgICAgICAgIAoKICMgc2VlIGdyb3VwIGNvZWZmaWNpZW50cyBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbHMKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkIDwtIGRhdGEudGFibGUodHJhbnNmb3JtKGFzLmRhdGEuZnJhbWUocmFuZWYoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCkpLCBsd3IgPSBjb25kdmFsIC0gMS45Nipjb25kc2QsIHVwciA9IGNvbmR2YWwgKyAxLjk2KmNvbmRzZCkpCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82OTgwNTUzMi9leHRyYWN0LXRoZS1jb25maWRlbmNlLWludGVydmFscy1vZi1sbWVyLXJhbmRvbS1lZmZlY3RzLXBsb3R0ZWQtd2l0aC1kb3RwbG90cmEKCgojT05MWSBTTE9QRVMKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkIDwtIGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFt0ZXJtID09ICJzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyIsXQoKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkWyxzdXJ2ZXlfdW5pdCA6PSBncnBdWyxzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyA6PSBjb25kdmFsXQoKCmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFssU2xvcGVfRGlyZWN0aW9uIDo9IGlmZWxzZShzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyA+IDAsICJQb3NpdGl2ZSIsIk5lZ2F0aXZlIildCgojCmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCA8LSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWRbY29sb3JfbGluaywgb24gPSAic3VydmV5X3VuaXQiXQoKCiNkb2VzIGl0IGNyb3NzIHplcm8/CmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFssc2lnbmlmaWNhbnQgOj0gaWZlbHNlKGx3ciA+MCAmIHVwcj4wLFQsaWZlbHNlKGx3cjwwICYgdXByPDAsVCxGKSldCgojZGVsZXRlIGFsbCBvYnMgdGhhdCBhcmUgc2lnbmlmaWNhbnQKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkLnIgPC0gZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkW3NpZ25pZmljYW50ID09IEYsXQoKI29yZGVyIHRhYmxlIGJ5IGNvZWZmaWNpZW50CnNldG9yZGVyKGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpCgpCQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlIDwtIHVuaXF1ZShmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWRbLC4oY29uZHZhbCxjb25kc2QsIGx3ciwgdXByLCBzdXJ2ZXlfdW5pdCwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIFNsb3BlX0RpcmVjdGlvbiwgaGV4LCBTdXJ2ZXlfTmFtZV9TZWFzb24sIHNpZ25pZmljYW50KV0pIAoKI2V4dHJhY3QgY29sb3IgaGV4ZXMKI3llYXIgYWRqIGNvZWYgb3JkZXIKY29sb3JfeWVhcl9hZGpfb3JkZXIgPC1CQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlWyxoZXhdCgojYWxwaGFiZXRpY2FsIG9yZGVyCkJDX2JhbGFuY2VkX2Zpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZC51bmlxdWUuYWxwaGEgPC0gc2V0b3JkZXIoQkNfYmFsYW5jZWRfZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkLnVuaXF1ZSwgU3VydmV5X05hbWVfU2Vhc29uKQpjb2xvcl9hbHBoYV9vcmRlciA8LSBCQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlLmFscGhhWyxoZXhdCgpnZ3Bsb3QoKSArCiAgICBnZW9tX2Vycm9yYmFyKGRhdGEgPSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQsIGFlcyh4ID0gcmVvcmRlcihTdXJ2ZXlfTmFtZV9TZWFzb24sIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKSAsIHkgPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgbGFiZWwgPSBTdXJ2ZXlfTmFtZV9TZWFzb24sIHltaW4gPSBsd3IsIHltYXggPSB1cHIpLCBmaWxsID0gImdyZXkiLCB3aWR0aCA9IDApICsgI2FkZCBjb25maWRlbmNlIGludGVydmFscwogIGdlb21fcG9pbnQoZGF0YSA9IGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCwgYWVzKHggPSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpICwgeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCBsYWJlbCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgCiAgICAgIGZpbGwgPSBTbG9wZV9EaXJlY3Rpb24pLCBzdGF0ID0gJ2lkZW50aXR5Jywgc2hhcGUgPSAyMSwgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygid2hpdGUiLCJibGFjayIpLCBuYW1lID0gIlNsb3BlIERpcmVjdGlvbiIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQuciwgYWVzKHggPSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpICwgeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCAKICAgICAgICAgIGxhYmVsID0gU3VydmV5X05hbWVfU2Vhc29uKSwgc3RhdCA9ICdpZGVudGl0eScsIGZpbGwgPSAiZ3JleSIsY29sb3IgPSAiZ3JleSIsIHNoYXBlID0gMjEpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCiAgeGxhYigiU3VydmV5IHVuaXQiKSArCiAgeWxhYigiQmFsYW5jZWQgQkMgZGlzc2ltaWxhcml0eSB+XG5yZWxhdGl2ZSBmaXNoaW5nIHByZXNzdXJlIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfY2xhc3NpYygpCgojc2NhdHRlcnBsb3QKZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cy5uYSA8LSBuYS5vbWl0KGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMsIGNvbHMgPSAic3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWciKSAjZGVsZXRlIGFueSByb3dzIHdpdGggTkFzCgojUHJlZGljdGVkIHZhbHVlcwpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLm5hJHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgPC0gcHJlZGljdChhbGxyZWdfZGlzc2ltaWxhcml0eV9maXNoaW5nX21lYW5fbW9kLHJlLmZvcm09TkEpICAjIyBwb3B1bGF0aW9uIGxldmVsCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEkcHJlZF9zdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZ19pbmRpdmlkdWFsIDwtIHByZWRpY3QoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCkgIyMgaW5kaXZpZHVhbCBsZXZlbAoKI2NvbmZpZGVuY2UgaW50ZXJ2YWxzCmZpc2hpbmdfY29uZml0IDwtIGNvbmZpbnQoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCwgb2xkTmFtZXMgPSBGKQoKI3VwcGVyIGxvd2VyIGJvdW5kcyBmcm9tIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmFbLHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfbHdyIDo9IGZpc2hpbmdfY29uZml0WzUsMV0gKyBmaXNoaW5nX2NvbmZpdFs2LDFdKnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnXSNsb3dlciBjb25maWRlbmNlIGludGVydmFsCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmFbLHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfdXByIDo9IGZpc2hpbmdfY29uZml0WzUsMl0gKyBmaXNoaW5nX2NvbmZpdFs2LDJdKnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnXSN1cHBlciBjb25maWRlbmNlIGludGVydmFsCgoKI2ZvciBhbGwgcmVnaW9ucwpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEpICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBwcmVzc3VyZSIsICB5ID0gIkJDIGJhbGFuY2VkIGRpc3NpbWlsYXJpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfaW5kaXZpZHVhbCwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpLCBsd2QgPSAxKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBwYWxldHRlXzM3KSArCiAgdGhlbWVfY2xhc3NpYygpCgoKCiNmb3IgYWxsIHJlZ2lvbnMgZmFjZXRlZApnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEpICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBwcmVzc3VyZSIsICB5ID0gIkJDIGJhbGFuY2VkIGRpc3NpbWlsYXJpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfaW5kaXZpZHVhbCwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gIHBhbGV0dGVfMzcpICsKICBmYWNldF93cmFwKH5zdXJ2ZXlfdW5pdCwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIikKCgoKYGBgCgpPdGhlciB2YXJpYWJsZXMgdG8gY29uc2lkZXIKCi0gU3BlY2llcyBudW1iZXIgKHNwcF9jb3VudF9hbm51YWwsIGRpZmZlcmVudCB2YWx1ZSBlYWNoIHJlZ2lvbiBhbmQgeWVhcikKClNwZWNpZXMgbnVtYmVyIGluIGEgeWVhciB2cy4gZGlzc2ltaWxhcml0eQpgYGB7cn0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNwcCBudW1iZXIiLCAgeSA9ICJCQyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBzcHBfY291bnRfYW5udWFsLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gIHBhbGV0dGVfMzcpICsKICMgZmFjZXRfd3JhcCh+c3VydmV5X3VuaXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIpCmBgYApTcGVjaWVzIG51bWJlciBpbiBhIHllYXIgdnMuIGRpc3NpbWlsYXJpdHkgfiB5ZWFyIGNvZWZmaWNpZW50CmBgYHtyfQpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLnVuaXF1ZSA8LSB1bmlxdWUoZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0c1ssLih5ZWFyLCBzcHBfY291bnRfYW5udWFsLCBicmF5X2NvZWYsIHN1cnZleV91bml0KV0pCgpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMudW5pcXVlKSArCiAgbGFicyh4ID0gIlNwcCBudW1iZXIiLCAgeSA9ICJCcmF5IEN1cnRpcyBkaXNzaW1pbGFyaXR5IH4geWVhciBjb2VmZmljaWVudCIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gc3BwX2NvdW50X2FubnVhbCwgeSA9IGJyYXlfY29lZiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBwYWxldHRlXzM3KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKwogIHRoZW1lX2NsYXNzaWMoKQpgYGAKUmVnaW9ucyB0aGF0IGFyZSBkaWZmZXJlbnRpYXRpbmcgKHBvc2l0aXZlIHNsb3BlKSB0ZW5kIHRvIGhhdmUgZmV3ZXIgI3Mgb2Ygc3BlY2llcy4gVGhlIGZldyByZWdpb25zIHdpdGggYSBsb3Qgb2Ygc3BlY2llcyAob3ZlciAxNTA7IEd1bGYgb2YgTWV4aWNvLCBXZXN0IENvYXN0IFVTLCBOb3J0aGVhc3QgVVMsIEd1bGYgb2YgQWxhc2thKSwgYWxsIGhhdmUgbmVnYXRpdmUgY29lZmZpY2llbnRzIChob21vZ2VuaXppbmcpLiBUaGlzIGlzIHRoZSBvcHBvc2l0ZSBvZiB3aGF0IEkgd291bGQgaGF2ZSBleHBlY3RlZCwgYXMgbW9yZSBzcGVjaWVzIGFjcm9zcyBhIHN1cnZleSByZWdpb24gd291bGQgaW50dWl0aXZlbHkgYWxsb3cgZm9yIG1vcmUgb3Bwb3J0dW5pdGllcyB0byBkaWZmZXJlbnRpYXRlLiAK